package main

import "fmt"

func test() {
	fmt.Println("匿名函数")
	// 将没有名称的函数赋值给变量，该函数称之为匿名函数
	a := func(s string) {
		fmt.Println("hello world first class function ", s)
	}
	a("user")

	// 直接调用匿名函数
	func(s string) {
		fmt.Println("hello world first no class function", s)
	}("user")
}

type add func(a int, b int) int

func test1() {
	fmt.Println("定义函数类型")
	var a add = func(a int, b int) int {
		return a + b
	}
	fmt.Println(a(1, 2))
}

// 将函数作为参数
func simple1(a func(a, b int) int) {
	fmt.Println(a(100, 20))
}

// 在其他函数中返回函数
func simple2() func(a, b int) int {
	f := func(a, b int) int {
		return a + b
	}
	return f
}

func test2() {
	fmt.Println("高阶函数")
	a := func(a, b int) int {
		return a + b
	}
	simple1(a)

	s := simple2()
	fmt.Println(s(1, 2))
}

func test3() {
	fmt.Println("闭包，当匿名函数体内变量在外边时候叫做闭包")
	x := 10
	a := func() {
		fmt.Println(x)
	}
	a()
}

type student struct {
	firstName string // 第一名称
	lastName  string // 第二名称
	grade     string // 年级
	country   string // 国家
}

// 筛选学生切片，接受筛选函数
func filter(s []student, f func(student) bool) []student {
	var r []student // 结果
	for _, v := range s {
		if f(v) == true {
			r = append(r, v)
		}
	}
	return r
}

func test4() {
	fmt.Println("头等函数实践")
	fmt.Println("可随时修改筛选条件，提高灵活性")
	s1 := student{
		firstName: "Naveen",
		lastName:  "Ramanathan",
		grade:     "A",
		country:   "India",
	}
	s2 := student{
		firstName: "Samuel",
		lastName:  "Johnson",
		grade:     "B",
		country:   "USA",
	}
	s := []student{s1, s2}
	f := filter(s, func(s student) bool {
		if s.grade == "A" {
			return false
		}
		return true
	})
	fmt.Println(f)
}

func main() {
	// test()
	// test1()
	// test2()
	// test3()
	test4()

}
